Skip to content

feat(ios): ship the xcframeworks through SwiftPM instead of npm - #206

Merged
triniwiz merged 2 commits into
masterfrom
feat/ios-spm-binaries
Nov 12, 2026
Merged

triniwiz merged 2 commits into
masterfrom
feat/ios-spm-binaries

Conversation

@triniwiz

Copy link
Copy Markdown
Member

The canvas npm tarball no longer fits on the registry: publishing 3.0.5 failed with 413 Payload Too Large (246 MB packed, 564 MB unpacked). Most of that is CanvasNative.xcframework. This moves the iOS frameworks for canvas, canvas-svg and audio-context out of the npm packages and serves them through SwiftPM from the GitHub release.

How it works

Each plugin's nativescript.config.ts now lists two local SwiftPM packages shipped inside the npm package:

  • platforms/ios/NativeScriptV8: the existing V8 header shim, unchanged.
  • platforms/ios/<Framework>Binary (CanvasNativeBinary, CanvasSVGBinary, AudioContextNativeBinary): a binaryTarget for the plugin's framework.

In the repo the binary target uses path:. During npm Release, tools/scripts/release-ios-binaries.sh runs before npm publish:

  • It zips each framework from dist and uploads it to the tag's GitHub release. If the release doesn't exist yet, it creates it with generated notes.
  • It writes url: and checksum: into the published Package.swift and removes the framework from the package.
  • It checks that the public URL serves the bytes the checksum expects.
  • A zip already on the release is reused, never replaced, because a package published by an earlier run of that tag expects its checksum.

The publish job now needs contents: write.

This is a local package with a remote binary target, not a repositoryURL as font-manager uses. SwiftPM clones a package repository's full git history before reading Package.swift, and this repo's history is several GB.

Repo changes

  • The frameworks are no longer tracked. Neither are the src-native/*/dist build outputs: 918 files.
    • After cloning, run npm run download.ios.frameworks (latest release, or -- <tag>), or build from source. The README has a new section on this.
    • Each <Framework>Binary folder has its own .gitignore. A root rule would make Nx leave the frameworks out of dist, as it already did once for the V8 headers.
  • A framework must not sit directly in platforms/ios: the CLI auto-links any .xcframework there, so it would be linked a second time next to the SwiftPM copy. The build scripts, place-native-artifacts.sh and build-native.yml now use the <Framework>Binary folders.
  • Versions: the canvas packages go to 3.0.6. 3.0.5 was never published to npm, and its tag points at a commit that still ships the frameworks. audio-context goes to 2.0.3, since 2.0.2 is already on npm and would otherwise be skipped.

Testing

  • Simulator app: a NativeScript app (CLI 9.1.1) using audio-context through the new package built for the iOS simulator and launched. The CLI added both SwiftPM packages, the framework was embedded once, and the app created NSCOpusDecoder, a class that exists only in the framework.
  • Remote binary target: a local package whose binaryTarget comes from a release URL resolved through Xcode and the CLI. Only the zip was downloaded, with no git clone.
  • Release script: run with gh and curl stubbed. It created a prerelease for a -beta tag and wrote the URL and checksum. The zip kept the Catalyst symlinks. A second run reused the existing assets and produced the same manifests.
  • Download script: run with a stubbed curl and with the real latest release, which has no zips yet and fails with a clear message.

Not tested yet:

  • App builds with canvas and canvas-svg through the new packages.
  • A real upload: the first npm Release run on the 3.0.6 tag does that.
  • Whether Nx copies the frameworks into dist despite the per-folder .gitignore. The release would fail its "Verify native artifacts" step if it didn't.

Follow-ups

  • Until 3.0.6 is released, download.ios.frameworks has nothing to fetch, so building from source is the only option for a fresh clone.
  • CanvasNative.podspec (v2.0.0) vendors src-native/canvas-ios/dist/CanvasNative.xcframework, which is no longer tracked. The plugins don't use it; it can probably be removed.

The canvas npm tarball outgrew the registry's size limit (413 on publish).

Each of canvas, canvas-svg and audio-context now references its framework
through a local SwiftPM package at platforms/ios/<Framework>Binary. In the
repo the binaryTarget points at a framework downloaded or built into that
directory. The npm Release workflow uploads the frameworks to the tag's
GitHub release and stamps the zip's url and checksum into the published
Package.swift, so SwiftPM downloads only the zip. A repositoryURL is not an
option: SwiftPM would clone this repo's multi-GB history first.

The frameworks and the src-native build output are no longer tracked. Run
`npm run download.ios.frameworks` after cloning, or build them from source
(see the README).
@coderabbitai

coderabbitai Bot commented Nov 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6fda0fc1-7e61-48f3-a340-d05b62a0c97c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@triniwiz
triniwiz merged commit 5aab332 into master Nov 12, 2026
20 of 25 checks passed
@triniwiz
triniwiz deleted the feat/ios-spm-binaries branch November 12, 2026 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant